package cn.ilikes.tools.hbase.jpa.indexs.lucenes;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.Properties;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexNotFoundException;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.LogDocMergePolicy;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.store.LockObtainFailedException;
import org.apache.lucene.util.Version;
import org.slf4j.Logger;
import org.wltea.analyzer.lucene.IKAnalyzer;

import cn.ilikes.tools.hbase.jpa.SysConfigs;
import cn.ilikes.tools.logs.Loggerfactory;

public class LocalLuceneIndexer extends LuceneIndexer {

	private static Logger logger = Loggerfactory.instance(LocalLuceneIndexer.class);
	/** The index. */
	private Directory directory;

	private String luceneDirPath;

	private static IndexWriter w;

	private void checkLuceneProperties(Properties properties) {
		if (properties.getProperty(SysConfigs.hbase_index_manager_path) == null)
			throw new LuceneIndexingException(" Lucene  Properties  not  contain : " + SysConfigs.hbase_index_manager_path);

	}

	public LocalLuceneIndexer(FlushType flushType, Properties properties) {
		super(flushType);
		checkLuceneProperties(properties);

		try {
			//			Directory sourceDir = FSDirectory.open(cleateIndexDirectory(luceneDirPath));
			//			directory = new RAMDirectory(sourceDir);
			luceneDirPath = properties.getProperty(SysConfigs.hbase_index_manager_path);
			directory = FSDirectory.open(createIndexDirectory(luceneDirPath));
		} catch (CorruptIndexException e) {
			throw new LuceneIndexingException(e);
		} catch (LockObtainFailedException e) {
			throw new LuceneIndexingException(e);
		} catch (IOException e) {
			throw new LuceneIndexingException(e);
		}
	}

	@Override
	protected void commitFSD() {

		//		w.commit();
		//		index.copy(index, FSDirectory.open(getIndexDirectory()), false);
	}

	private File createIndexDirectory(String luceneDirPath) {
		Loggerfactory.info(logger, "local luence index dir path  :  " + luceneDirPath);
		this.luceneDirPath = luceneDirPath;
		File file = new File(luceneDirPath);
		if (file.exists())
			return file;
		if (!file.isDirectory()) {
			file.mkdirs();
		}

		return file;

	}

	protected boolean isEmptyDir() {
		File file = new File(luceneDirPath);

		if (file.list(new FilenameFilter() {

			@Override
			public boolean accept(File dir, String name) {
				return (name.startsWith("segments"));
			}
		}).length == 0)
			return true;
		else
			return false;
	}

	@Override
	protected IndexWriter createIndexWriter() throws LuceneIndexingException {

		try {
			if (w == null) {
				synchronized (ENTITY_ID_FIELD) {
					if (w == null)
						w = new IndexWriter(directory, new IndexWriterConfig(Version.LUCENE_34, this.getAnalyzer()));
					w.setMergePolicy(new LogDocMergePolicy());
					w.setMergeFactor(1000);
					w.getConfig().setRAMBufferSizeMB(32);
				}
			}

			return w;
		} catch (CorruptIndexException e) {
			throw new LuceneIndexingException("create Index Reader  no success ! ", e);
		} catch (LockObtainFailedException e) {
			throw new LuceneIndexingException("create Index Reader  no success ! ", e);
		} catch (IOException e) {
			throw new LuceneIndexingException("create Index Reader  no success ! ", e);
		}

	}

	@Override
	protected IndexReader createIndexReader() throws LuceneIndexingException {

		try {
			IndexReader reader = IndexReader.open(directory);
			return reader;
		} catch (IndexNotFoundException e) {

			Loggerfactory.warn(logger, e.getMessage());
			return null;
		} catch (CorruptIndexException e) {
			throw new LuceneIndexingException("create Index Reader  no success ! ", e);
		} catch (IOException e) {
			throw new LuceneIndexingException("create Index Reader  no success ! ", e);
		}
	}

	@Override
	protected Analyzer getAnalyzer() {

		return new IKAnalyzer();
	}

}
